/*
 * Copyright: 2018 smarabbit studio.
 *
 * Licensed under the Confluent Community License; you may not use this file
 * except in compliance with the License.  You may obtain a copy of the License at
 *
 * http://www.confluent.io/confluent-community-license
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations under the License.
 *
 * @作   者： 黄开晖 (117227773@qq.com)
 * @日   期:  2019年2月24日
 */
package com.massyframework.beanskin.runtime.service.metadata;


import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.massyframework.beanskin.service.metadata.MethodMetadata;


/**
 * 实现{@link MethodMetadata}的缺省类
 *
 */
public final class DefaultMethodMetadata extends MetadataBase<Method> implements MethodMetadata {

	/**
	 * 构造方法
	 * @param original {@link Method},方法
	 */
	public DefaultMethodMetadata(Method original) {
		super(original);
	}
	
	/* (non-Javadoc)
	 * @see com.massyframework.metadata.Metadata#findAnnotation(java.lang.Class)
	 */
	@Override
	public <A extends Annotation> A findAnnotation(Class<A> annoType) {
		return this.getOriginal().getDeclaredAnnotation(annoType);
	}

	/* (non-Javadoc)
	 * @see com.massyframework.metadata.Metadata#findAnnotations(java.lang.Class)
	 */
	@Override
	public <A extends Annotation> A[] findAnnotations(Class<A> annoType) {
		return this.getOriginal().getDeclaredAnnotationsByType(annoType);
	}
	
	/* (non-Javadoc)
	 * @see com.massyframework.metadata.MethodMetadata#matched(java.lang.String, java.lang.Class[])
	 */
	@Override
	public boolean matched(String methodName, Class<?>[] paramTypes) {
		if (!this.getName().equals(methodName)) {
			return false;
		}
		
		int size = this.getOriginal().getParameterCount();
		if (paramTypes.length != size) return false;
		
		for (int i=0; i<size; i++) {
			if (paramTypes[i] != this.getOriginal().getParameterTypes()[i]) {
				return false;
			}
		}
		
		return true;
	}

	/* (non-Javadoc)
	 * @see com.massyframework.metadata.MethodMetadata#invoke(java.lang.Object, java.lang.Object[])
	 */
	@Override
	public Object invoke(Object target, Object... args)
			throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		if (!this.getOriginal().isAccessible()) {
			this.getOriginal().setAccessible(true);
		}
		return this.getOriginal().invoke(target, args);
	}

	/* (non-Javadoc)
	 * @see com.massyframework.metadata.Metadata#getName()
	 */
	@Override
	public String getName() {
		return this.getOriginal().getName();
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "DefaultMethodMetadata [method =" + this.getOriginal().toGenericString() + "]";
	}

}
